(* Dimensions d'une image *)
let get_dims img =
  ((Sdlvideo.surface_info img).Sdlvideo.w,
	 (Sdlvideo.surface_info img).Sdlvideo.h)

let search_altitude filename color = match color with (r,g,b) ->
  let altitude = ref "" in
  let color_string =
    "("^(string_of_int r)
    ^","^(string_of_int g)
    ^","^(string_of_int b)^")" in
  let file = open_in filename in
    try
      while true do
	let line = input_line file in
	let current_color = ref "" in
	let current_altitude = ref "" in
	let i = ref 0 in
	let is_color_done = ref false in
	  while (!i < String.length line) do
	    if not (!is_color_done) then
              if(line.[!i] = ' ')then
		is_color_done := true
              else
		current_color := !current_color^(Char.escaped(line.[!i]))
	    else
              current_altitude :=
		!current_altitude^(Char.escaped(line.[!i]));
	    i := !i + 1;
	  done;
	  if (color_string = !current_color) then
	    begin
              altitude := !current_altitude;
            end
      done;
      !altitude
    with
	End_of_file -> close_in file;
	  !altitude


(* fonction de recuperation des triplets de coordonnees *)
let make_vertices image space altitude =
  let vertexes = ref [] in
  let (width,height) = get_dims image in
  for i=0 to width-1 do
    for j=0 to height-1 do
      if (i mod space = 0 && j mod space = 0) then
	let z = float_of_string
		(search_altitude altitude
		   (Sdlvideo.get_pixel_color image i j)
		) in
                vertexes := (float_of_int (i - width / 2)
                             ,z
                             ,float_of_int (j - height / 2))::(!vertexes)
    done
  done;
  let vs = Array.of_list (!vertexes) in
  vs

(*fonction qui cree les faces *) (*optimisation possible*)
let make_faces image space vs =
  let length = Array.length vs in
  let f = Array.make length ((0,0,0),(0,0,0)) in
  let (width,height) = get_dims image in
  let nb_ind = (width / space) + 1 in
  for i = 0 to length-1 do
    if (i < (length - nb_ind - 1) && (((i+1) mod nb_ind) <> 0)) then
      f.(i) <- ((i+1,  i+2, i + nb_ind+2),(i+1 , i+nb_ind+1,
					   i+nb_ind+2))
  done;
  f

(* ecrit le .obj *)
let write_obj vs fs filename =
  let file = open_out filename in
    for i = 0 to (Array.length vs)-1 do
      let (x,y,z) = vs.(i) in
	output_string file ("v "^(string_of_float x)
			    ^" "^(string_of_float y)
                            ^" "^(string_of_float z)
			    ^"\n")
    done;
    for i = 0 to (Array.length fs)-1 do
      let ((a,b,c),(i,j,k)) = fs.(i) in (*avec i=a et c=k*)
	if ((a,b,c) <> (0,0,0)) then
	  begin
	    output_string file ("f "^(string_of_int a)
				^" "^(string_of_int b)
				^" "^(string_of_int c)
				^"\n");
	    output_string file ("f "^(string_of_int i)
				^" "^(string_of_int j)
				^" "^(string_of_int k)
				^"\n")
	  end
    done;
    close_out file

(*decompose une ligne du type "v x y z" et renvoie le triplet (x,y,z)*)
let decompose_v line =
  let strlist = Str.split (Str.regexp " ") line in
  (float_of_string (List.nth strlist 1),
   float_of_string (List.nth strlist 2),
   float_of_string (List.nth strlist 3))

(*decompose une ligne du type "f a b c" et renvoie le triplet (a,b,c)*)
let decompose_f line =
  let strlist = Str.split (Str.regexp " ") line in
  (int_of_string (List.nth strlist 1),
   int_of_string (List.nth strlist 2),
   int_of_string (List.nth strlist 3))

(* parse le .obj et renvoie un couplet contenant un tableau de sommets et une liste de
   faces ?*)
let read_obj filename =
  let file = open_in filename in
  let vertexes = Array.make (800*600) (0.,0.,0.) in
  let faces = ref [] in
  let i = ref 0 in
  try
    while true do
      let line = input_line file in
      if line.[0] = 'v' then
	vertexes.(!i) <- decompose_v line
      else
	faces := (decompose_f line)::(!faces);
      i := !i + 1;
    done;
    (vertexes,!faces)
  with
      End_of_file -> close_in file;
	(vertexes, !faces)

(* Fonction d'appel *)
let objectize image space filename altitude =
  let vs = make_vertices image space altitude in
    write_obj vs (make_faces image space vs) filename
